Skip to content

fix(assets): resolver Character Creator refs via upload absoluto - #220

Merged
IAnMove merged 1 commit into
feat/asset-picker-labsfrom
cursor/critical-bug-management-d694
Sep 7, 2026
Merged

fix(assets): resolver Character Creator refs via upload absoluto#220
IAnMove merged 1 commit into
feat/asset-picker-labsfrom
cursor/critical-bug-management-d694

Conversation

@cursor

@cursor cursor Bot commented Sep 7, 2026

Copy link
Copy Markdown

Resumen ejecutivo

Esta primera sección está pensada para project managers y revisores no técnicos. Mantén el detalle técnico completo más abajo.

Qué cambia

ensureUploadsPath deja de inventar uploads/${nombre} y copia cada imagen de Labs por /api/v1/upload para devolver la ruta absoluta que ya entrega esa API.

Para qué sirve

El flujo por defecto de Character Creator (foto del dispositivo + A Prompt vacío) llamaba a auto-describe con uploads/hero.png. El backend resuelve nombres relativos dentro de uploads/, así que buscaba uploads/uploads/hero.png y respondía 400. Sin esto no se puede generar la órbita.

Impacto para el usuario

Elegir una foto local en Character Creator y pulsar generar vuelve a funcionar. Series sigue importando, ahora con una copia extra en uploads/.

Riesgo

  • Bajo
  • Medio
  • Alto

Estado

  • En desarrollo
  • Listo para revisión
  • Bloqueado por CI o revisión
  • Requiere migración o acción manual

Summary

Minimal fix for PR #218. ensureUploadsPath short-circuited already-uploaded catalog/device picks as uploads/${item.name}. Character Creator auto-describe (needsVisionDescribe when the A prompt is empty — the default) resolves relative names under the uploads root via _resolve_model3d_input_path, so that path became uploads/uploads/${name} and the orbit job 400'd with "Character reference image not found".

The helper now always fetches the chosen image and POSTs /api/v1/upload, returning the absolute path that Series import, describe, and H3 isfile checks already accept.

Overview

  1. User picks a local image in Character Creator (AssetInput already uploaded it to /api/v1/uploads/<uuid>.png).
  2. applyRef calls ensureUploadsPath.
  3. Before: returned { path: "uploads/<name>" }. After: re-copies and returns { path: "<cwd>/uploads/<new-uuid>.png" }.
  4. Empty A prompt → describeCharacterRefs({ image_paths }) finds the file.
  5. Orbit generate and Series importSeriesAsset keep working with the same absolute path.

Detailed changes

Backend

None. _resolve_model3d_input_path is unchanged; callers now send a path it already understands.

UI and Wizard

  • ui/src/lib/labsImagePick.ts: always copy through uploadImage.
  • Tests updated so upload URLs no longer skip the POST.

Data, provenance and compatibility

Device/catalog picks that were already uploads get a second copy in uploads/. Same as the previous catalog (non-upload) branch. No persisted schema change.

Files and ownership

  • ui/src/lib/labsImagePick.ts — the helper introduced in feat(assets): migrate Labs CHR/STY fields to AssetInput #218.
  • ui/tests/labsImagePick.test.mjs — locks the absolute-path contract.
  • ui/tests/seriesLabsPicker.test.tsx — Series import now expects the upload API path.
  • Picker core, Tools, Scene3D, Wizard/Director: untouched.

Validation

  • Date (UTC): 2026-09-07

  • Base SHA: 719d0d1 (feat/asset-picker-labs)

  • Head SHA: 7b4584c

  • Validation scope: focused

  • python scripts/verify_clean_repo.py

  • python -m compileall -q app/services app/launch.py scripts

  • Focused Python tests: N/A (UI-only)

  • cd ui && npm run i18n:check

  • UI tests: npx tsx --tsconfig tsconfig.app.json --import ./tests/setupI18n.ts --test tests/labsImagePick.test.mjs tests/seriesLabsPicker.test.tsx → 3 passed; plus tests/seriesShotSelection.test.tsx tests/seriesShotsAccessibility.test.tsx tests/characterCreator.test.tsx → 11 passed

  • cd ui && npm run lint -- --max-warnings=0

  • cd ui && npm run build

  • git diff --check

  • E2E/smoke checks: N/A — path-resolution unit/integration tests cover the trigger

Code quality

  • Score: pending CI
  • Complexity trend: pending CI
  • Production LOC trend: pending CI
  • Regression versus main: pending CI
  • Ratchet: pending CI

CI and review

  • CI of this HEAD: pending

  • Independent agent review of this HEAD: pending

  • Human merge click (operational, not code review): pending

  • Reviewed at current HEAD

  • Earlier review; HEAD has changed since (stale)

  • Pending

  • Unavailable

Coste de la tarea

  • Tests simulados: 0 tokens externos
  • Tests reales: N/A
  • Llamadas LLM externas: 0
  • Tokens de prompt: N/A
  • Tokens de respuesta: N/A
  • Tokens totales: N/A
  • Generaciones de imágenes/audio/vídeo: 0
  • Tiempo transcurrido: N/A
  • Proveedores/modelos: N/A

Notes and limitations

Stacked on #218 (feat/asset-picker-labs). Merge this into that branch before merging Labs. Local picks now create a second uploads copy (AssetInput already uploaded once).

Follow-up work

None required for this bug. Optional later: teach _resolve_model3d_input_path to strip a redundant uploads/ prefix so relative uploads/name paths also resolve.

Checklist

  • The executive summary is understandable without reading the code.
  • The detailed Summary/Overview has not been removed or shortened.
  • Tests and their actual results are recorded.
  • Generated assets, secrets and local-only files are not committed.
  • Required CI and Cursor/Bugbot review are complete, or the PR is clearly marked as waiting for them.
Open in Web View Automation 

Note

Low Risk
UI-only path handling fix with no backend or schema changes; extra upload copies are the main behavioral side effect.

Overview
ensureUploadsPath no longer short-circuits images that already live under /api/v1/uploads/ — every Labs pick is fetched and re-posted through /api/v1/upload, and callers get the API’s absolute path instead of a synthetic uploads/${name}.

That fixes Character Creator’s default flow (device photo + empty A prompt): auto-describe was resolving uploads/hero.png as uploads/uploads/hero.png and returning 400. Series canon import and other consumers now receive the same absolute path contract.

Tests were updated: unit tests mock fetch + upload for both upload URLs and workspace file URLs; the Series Labs picker integration expects uploadPath: '/abs/uploads/copied.png'. Trade-off: picks that were already in uploads get an extra copy in uploads/.

Reviewed by Cursor Bugbot for commit 7b4584c. Configure here.

…resolve refs

ensureUploadsPath returned uploads/${name} for already-uploaded images.
Auto-describe resolves relative names under the uploads root, so that
path became uploads/uploads/${name} and the default empty-prompt orbit
flow 400'd. Always copy through /api/v1/upload and keep the absolute
path the upload API already returns.

Co-authored-by: ignaciodelcano+dcl <ignaciodelcano+dcl@gmail.com>
@IAnMove
IAnMove marked this pull request as ready for review September 7, 2026 14:15
@IAnMove
IAnMove merged commit 498ce9c into feat/asset-picker-labs Sep 7, 2026
@cursor

cursor Bot commented Sep 7, 2026

Copy link
Copy Markdown
Author

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_1e8ba4a3-ec07-46c4-8b3f-b428e073a8fe)

@IAnMove

IAnMove commented Sep 7, 2026

Copy link
Copy Markdown
Owner

This was merged into feat/asset-picker-labs after that branch had already landed on development via #218, so the fix never reached development. Cherry-picked in #222.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants